package com.google.code.stalkernet.database;

import com.google.code.stalkernet.database.event.DatabaseListener;
import com.google.code.stalkernet.entry.Entry;
import com.google.code.stalkernet.entry.EntryBody;
import com.google.code.stalkernet.entry.EntryID;

/**
 * Stalker.Net database.
 *
 * @author Mikhail Vladimirov
 */
public interface Database
{
    /**
     * Add listener to be notified about database-related events.
     *
     * @param databaseListener listener to be added
     */
    public void addDatabaseListener (DatabaseListener databaseListener);

    /**
     * Remove listener notified about database-related events.
     *
     * @param databaseListener listener to be removed
     */
    public void removeDatabaseListener (DatabaseListener databaseListener);

    /**
     * Get IDs of leaf entries of the database, i.e. IDs of entries that are
     * not referred from any other entries.
     *
     * @return an array of {@link EntryID} objects
     */
    public EntryID [] getLeafIDs ();

    /**
     * Tells whether database has entry with given ID.
     *
     * @param entryID entry ID to check
     * @return <code>true</code> if database has entry with given ID,
     *         <code>false</code> otherwise
     */
    public boolean hasEntry (EntryID entryID);

    /**
     * Get entry by entry ID.
     *
     * @param entryID entry ID
     * @return {@link Entry} with given entry ID
     * @throws NoSuchEntryException if there is no entry with given ID in the
     *         database
     */
    public Entry getEntry (EntryID entryID) throws NoSuchEntryException;

    /**
     * Add an entry to the database.
     *
     * @param entry entry to be added
     * @throws EntryAlreadyExistsException if entry is already in the database
     * @throws NoSuchEntryException if the database does not have all parents
     *         of given entry
     */
    public void addEntry (Entry entry)
        throws EntryAlreadyExistsException, NoSuchEntryException;

    /**
     * Create new entry that can be added to the database.
     *
     * @param entryBody body for the new entry
     * @return new entry
     */
    public Entry createEntry (EntryBody entryBody);
}
